package com.xssn.fjnd.content.service.impl;

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xssn.fjnd.content.req.VideoREQ;
import com.xssn.fjnd.content.utils.AliyunVodProperties;
import com.xssn.fjnd.content.utils.AliyunVodSDKUtils;
import com.xssn.fjnd.entities.Video;
import com.xssn.fjnd.content.mapper.VideoMapper;
import com.xssn.fjnd.content.service.IVideoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xssn.fjnd.feign.req.UserInfoREQ;
import com.xssn.util.base.Result;
import com.xssn.util.exception.GlobalExceptionHandler;
import com.xssn.util.exception.XssnException;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * <p>
 * 视频信息表 服务实现类
 * </p>
 *
 * @author 线狮少年
 * @since 2023-08-14
 */
@Slf4j
@Service
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements IVideoService {

    @Autowired
    private IVideoService videoService;

    //上传阿里云视频
    @Override
    public String uploadVideo(MultipartFile file) {

        try {

            //fileName: 上传文件原始名称
            String fileName = file.getOriginalFilename();
            //title: 上传文件显示名称
            String title = fileName.substring(0, fileName.lastIndexOf("."));
            //inputStream: 上传文件输入流
            InputStream inputStream = file.getInputStream();


            //本地文件上传
            UploadStreamRequest request = new UploadStreamRequest(
                    AliyunVodProperties.ACCESS_KEY_ID,
                    AliyunVodProperties.ACCESS_KEY_SECRET,
                    title, fileName, inputStream);

            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadStreamResponse response = uploader.uploadStream(request);

            //如果设置回调URL无效，不影响视频上传，可以返回VideoId同时会返回错误码。
            // 其他情况上传失败时，VideoId为空，此时需要根据返回错误码分析具体错误原因
            String videoId = response.getVideoId();
            if (!response.isSuccess()) {
                String errorMessage = "阿里云上传错误：" + "code：" + response.getCode() + ", message：" + response.getMessage();
                log.warn(errorMessage);
                if (StringUtils.isEmpty(videoId)) {
                    throw new XssnException(20001,errorMessage);
                }
            }
            return videoId;
        } catch (IOException e) {
            throw new XssnException(20001, "线狮少年-->阿里云 vod 服务上传失败");
        }
    }


    /**
     * 根据id删除阿里云视频
     * @param videoId
     * @return
     */
    @Override
    public Result deleteVideoBySourceId(String videoId) {
        try {
            DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                    AliyunVodProperties.ACCESS_KEY_ID,
                    AliyunVodProperties.ACCESS_KEY_SECRET);
            //获取request对象
            DeleteVideoRequest request = new DeleteVideoRequest();
            //设置id
            request.setVideoIds(videoId);
            //获取response对象
            DeleteVideoResponse response = client.getAcsResponse(request);
            System.out.println("requestId =  " + response.getRequestId());


        } catch (ClientException e) {
            throw new XssnException(20001, "视频删除失败");
        }
        return Result.ok();
    }


    /**
     * 功能描述：根据 阿里云视频id列表 删除视频，批量删除，每次最多删除20个
     *
     * @param videoIdList 阿里云视频id列表
     * @return R 返回给前端的数据
     * @author cakin
     * @date 2020/12/13
     */
    @Override
    public void removeVideoByIdList(List<String> videoIdList) throws ClientException {
        DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                AliyunVodProperties.ACCESS_KEY_ID,
                AliyunVodProperties.ACCESS_KEY_SECRET);
        DeleteVideoRequest request = new DeleteVideoRequest();
        int size = videoIdList.size(); // id列表的长度
        StringBuffer idListStr = new StringBuffer(); //组装好的字符串
        for (int i = 1; i <= size; i++) {
            idListStr.append(videoIdList.get(i - 1));
            if (i == size || i % 20 == 0) { // 当是最后一个或是20的倍数，就开始批量删除
                // 删除，支持传入多个视频ID，多个用逗号分隔。id不能超过20个
                log.info("idListStr = " + idListStr.toString());
                request.setVideoIds(idListStr.toString());
                client.getAcsResponse(request);
                // 重置idListStr
                idListStr = new StringBuffer();
            } else {
                idListStr.append(",");
            }
        }
    }

    @Override
    public String getPlayAuth(String videoSourceId) throws ClientException {
        //初始化client对象
        DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                AliyunVodProperties.ACCESS_KEY_ID,
                AliyunVodProperties.ACCESS_KEY_SECRET);


        //创建请求对象
        GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest ();
        request.setVideoId(videoSourceId);

        //获取响应
        GetVideoPlayAuthResponse response = client.getAcsResponse(request);

        return response.getPlayAuth();
    }

    @Override
    public String getPlayInfo(String videoSourceId) throws ClientException {
        DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                AliyunVodProperties.ACCESS_KEY_ID,
                AliyunVodProperties.ACCESS_KEY_SECRET);

        //创建请求对象
        GetPlayInfoRequest request = new GetPlayInfoRequest();
        request.setVideoId(videoSourceId);

        //获取响应
        GetPlayInfoResponse response = client.getAcsResponse(request);

        List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();

        String playURL = null;
        for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
             playURL = playInfo.getPlayURL();
        }
        return playURL;
    }

    @Override
    public Result queryPage(VideoREQ req) {
        QueryWrapper<Video> wrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(req.getTitle())) {
            wrapper.like("title", req.getTitle());
        }

        if(req.getType() != null) {
            wrapper.eq("type", req.getType());
        }
        IPage<Video> page = baseMapper.selectPage(req.getPage(), wrapper);
        return Result.ok(page);
    }

    @Override
    public void saveVideoInfo(Video video) {
        Video videoVo = new Video();
        BeanUtils.copyProperties(video, videoVo);
        boolean result = this.save(videoVo);

        if(!result){
            throw new XssnException(20001, "视频信息保存失败");
        }
    }

    @Transactional
    @Override
    public Result deleteVideoById(String id) {
        String videoSourceId = baseMapper.selectById(id).getVideoSourceId();
        //先删除对象
        baseMapper.deleteById(id);
        //再到阿里云删除视频，  顺序反了会无权限
        System.out.println(videoSourceId);
        if (!StringUtils.isEmpty(videoSourceId)) {
            // videoSourceId不为空说明存在 -->删除
            videoService.deleteVideoBySourceId(videoSourceId);
        }
        return Result.ok();
    }

    @Override
    public void updateVideoInfoById(Video video) {
        Video videoVo = new Video();
        BeanUtils.copyProperties(video, videoVo);
        boolean result = this.updateById(videoVo);
        if (!result) {
            throw new XssnException(20001, "视频信息更新失败");
        }
    }

    @Override
    public boolean updateUserInfo(UserInfoREQ req) {
        return baseMapper.updateUserInfo(req);
    }

    @Override
    public Result searchVideoByType(Integer type) {
        QueryWrapper<Video> wrapper = new QueryWrapper<>();

        if(type != null) {
            wrapper.eq("type", type);
        }
        wrapper.orderByDesc("play_count").last("limit 4");
        List<Video> videos = baseMapper.selectList(wrapper);
        return Result.ok(videos);
    }

    @Override
    public Result updatePlayCount(String id) {
        if(StringUtils.isEmpty(id)) {
            return Result.error("无效操作");
        }
        Video video = baseMapper.selectById(id);
        if(video == null){
            return Result.error("文章不存在");
        }
        video.setPlayCount( video.getPlayCount() + 1 );

        baseMapper.updateById(video);
        return Result.ok();
    }

    @Override
    public Result updateThumhup(String id, int count) {
        if(count != -1 && count != 1) {
            return Result.error("无效操作");
        }

        if(StringUtils.isEmpty(id)) {
            return Result.error("无效操作");
        }

        // 查询这篇文章现有数据，查询到后，将点赞数进行更新
        Video video = baseMapper.selectById(id);
        if(video == null) {
            return Result.error("视频不存在");
        }

        if(video.getThumhup() <= 0 && count == -1) {
            return Result.error("无效操作");
        }
        // 更新点赞数
        video.setThumhup( video.getThumhup() + count );
        baseMapper.updateById(video);

        return Result.ok();
    }


}
